package com.ds.rad.service;

import com.ds.annotation.MethodChinaName;
import com.ds.annotation.UserSpace;
import com.ds.common.JDSException;
import com.ds.common.md5.MD5;
import com.ds.common.util.IOUtility;
import com.ds.common.util.StringUtility;
import com.ds.config.ErrorListResultModel;
import com.ds.config.ErrorResultModel;
import com.ds.config.JDSConfig;
import com.ds.config.ResultModel;
import com.ds.context.JDSActionContext;
import com.ds.esd.dsm.DSMFactory;
import com.ds.esd.dsm.aggregation.DomainInst;
import com.ds.esd.engine.*;
import com.ds.esd.engine.enums.PackagePathType;
import com.ds.esd.engine.enums.PackageType;
import com.ds.esd.engine.enums.ProjectDefAccess;
import com.ds.rad.bean.XUIFile;
import com.ds.vfs.FileInfo;
import com.ds.vfs.VFSConstants;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;

@Controller
@RequestMapping(value = {"/RAD/"})
@MethodChinaName(cname = "XUI编辑器")
public class RADEditor {

    @RequestMapping(value = {"export"}, method = {RequestMethod.GET})
    @ResponseBody
    public ResultModel<Boolean> export(String projectName) {
        ResultModel<Boolean> resultModel = new ResultModel<Boolean>();
        try {
            ProjectVersion version = getClient().getProjectVersionByName(projectName);
            List<FileInfo> fileInfos = version.getRootFolder().getFileListRecursively();
            for (FileInfo fileInfo : fileInfos) {
                if (!fileInfo.getName().endsWith(".cls")) {
                    String localPath = JDSConfig.Config.tempPath().getPath() + File.separator;
                    String realPath = StringUtility.replace(fileInfo.getPath(), version.getRootFolder().getPath(), "/");
                    File file = new File(localPath + realPath);
                    InputStream input = fileInfo.getCurrentVersion().getInputStream();
                    if (file.getParentFile() != null && !file.getParentFile().exists()) {
                        file.getParentFile().mkdirs();
                    }
                    if (!file.exists()) {
                        file.createNewFile();
                    }
                    FileOutputStream output = new FileOutputStream(file);
                    IOUtility.copy(input, output);
                    IOUtility.shutdownStream(input);
                    IOUtility.shutdownStream(output);
                }

            }
            JDSActionContext.getActionContext().getContext().put("build", "false");
            Set<EUModule> modules = version.getAllModule();
            for (EUModule module : modules) {
                String localPath = JDSConfig.Config.tempPath().getPath() + File.separator;
                File file = new File(localPath + "cls/" + MD5.getHashString(module.getClassName()));
                StringBuffer json = ESDFacrory.getAdminESDClient().genJSON(module, null, true);
                InputStream input = new ByteArrayInputStream(json.toString().getBytes(VFSConstants.Default_Encoding));
                if (file.getParentFile() != null && !file.getParentFile().exists()) {
                    file.getParentFile().mkdirs();
                }

                if (!file.exists()) {
                    file.createNewFile();
                }
                FileOutputStream output = new FileOutputStream(file);
                IOUtility.copy(input, output);
                IOUtility.shutdownStream(input);
                IOUtility.shutdownStream(output);
            }
            JDSActionContext.getActionContext().getContext().remove("build");

        } catch (Exception e) {
            e.printStackTrace();
        }
        //本地备份文件
        return resultModel;
    }

    private List<XUIFile> getDomainList(String projectName) {
        ProjectDefAccess[] sysDef = new ProjectDefAccess[]{ProjectDefAccess.admin, ProjectDefAccess.sys, ProjectDefAccess.DSM};
        List<XUIFile> dataList = new ArrayList<>();
        List<DomainInst> domainInsts = new ArrayList<>();
        try {
            ProjectVersion version = ESDFacrory.getAdminESDClient().getProjectVersionByName(projectName);
            ProjectDefAccess projectDefAccess = version.getProject().getProjectType();
            if (Arrays.asList(sysDef).contains(projectDefAccess)) {
                domainInsts = DSMFactory.getInstance().findDomainInst(projectName, UserSpace.SYS);
                PackageType[] packageTypes = projectDefAccess.getPackageTypes();
                List<EUPackage> packages = ESDFacrory.getAdminESDClient().getTopPackages(version.getVersionName());
                for (EUPackage euPackage : packages) {
                    PackagePathType packagePathType = euPackage.getPackagePathType();
                    if (packagePathType != null && packagePathType.getApiType() != null) {
                        if (Arrays.asList(packageTypes).contains(packagePathType.getApiType())) {
                            if (euPackage.getFolder().getFileList().size() > 0 || euPackage.getFolder().getChildrenList().size() > 0) {
                                dataList.add(new XUIFile(euPackage));
                            }
                        } else if (Arrays.asList(packageTypes).contains(packagePathType)) {
                            dataList.add(new XUIFile(euPackage));
                        }
                    }
                }

            } else {
                domainInsts = DSMFactory.getInstance().getAllUserDomainInst(projectName);
            }

            for (DomainInst domainInst : domainInsts) {
                dataList.add(new XUIFile(domainInst, version));
            }


            EUPackage euPackage = ESDFacrory.getAdminESDClient().getPackageByPath(version.getVersionName(), version.getProject().getProjectName());
            if (euPackage != null) {
                List<EUPackage> childPackageList = euPackage.listChildren();
                Set<EUModule> modules = euPackage.listModules();
                for (EUPackage childPackage : childPackageList) {
                    boolean isSys = false;
                    for (UserSpace userSpace : UserSpace.values()) {
                        if (childPackage.getName().equals(userSpace.getType().toLowerCase())) {
                            isSys = true;
                        }
                    }
                    if (!isSys) {
                        dataList.add(new XUIFile(childPackage));
                    }
                }

                for (EUModule euModule : modules) {
                    dataList.add(new XUIFile(euModule));
                }
            }

        } catch (JDSException e) {
            e.printStackTrace();
        }

        return dataList;

    }


    @MethodChinaName(cname = "装载工程")
    @RequestMapping(value = {"openProject"}, method = {RequestMethod.GET})
    public @ResponseBody
    ResultModel<ProjectInfo> openProject( String projectName) {
        ResultModel<ProjectInfo> result = new ResultModel<ProjectInfo>();
        List<XUIFile> modules = new ArrayList<XUIFile>();
        String[] systemFiles = new String[]{"ProjectConfig.cfg", "xuiconf.js"};
        try {
            ProjectVersion projectVersion = getClient().getProjectVersionByName(projectName);
            Project project = projectVersion.getProject();
            modules = getDomainList(projectName);
            List<FileInfo> infos = projectVersion.getRootFolder().getFileList();
            for (FileInfo fileInfo : infos) {
                boolean isSystem = false;
                for (String name : systemFiles) {
                    if (fileInfo.getName().equals(name)) {
                        isSystem = true;
                    }
                }
                if (!isSystem) {
                    if (!fileInfo.getName().endsWith(".cls")) {
                        modules.add(new XUIFile(fileInfo, projectVersion));
                    } else {
                        EUModule module = projectVersion.getModule(fileInfo.getPath());
                        if (module != null) {
                            modules.add(new XUIFile(module));
                        }
                    }
                }
            }
            ProjectInfo projectInfo = new ProjectInfo();
            projectInfo.setFiles(modules);
            projectInfo.setIndex(project.getConfig().getIndex());
            result.setData(projectInfo);
        } catch (JDSException e) {
            result = new ErrorResultModel<>();
            ((ErrorListResultModel) result).setErrcode(JDSException.APPLICATIONNOTFOUNDERROR);
            ((ErrorListResultModel) result).setErrdes(e.getMessage());

        }

        return result;
    }


    @MethodChinaName(cname = "获取工程配置信息")
    @RequestMapping(value = {"getProjectConfig"}, produces = "application/javascript;charset=utf-8", method = {RequestMethod.GET, RequestMethod.POST})
    public @ResponseBody
    String getProjectConfig( String projectName) {
        String conf = "{}";
        try {
            conf = this.getClient().readFileAsString("xuiconf.js", projectName);
        } catch (JDSException e) {
            e.printStackTrace();
            return e.getMessage();
        }
        return conf;
    }


    ESDClient getClient() throws JDSException {
        ESDClient client = ESDFacrory.getAdminESDClient();
        return client;
    }

}
